Trò chơi Angry Birds trong UNITY Engine
31.653 lượt xem;
1 using UnityEngine;
2 using System.Collections;
3 using Assets.Scripts;
4 using System;
5
6 public class SlingShot : MonoBehaviour
7 {
8
9 //a vector that points in the middle between left and right parts of the slingshot
10 private Vector3 SlingshotMiddleVector;
11
12 [HideInInspector]
13 public SlingshotState slingshotState;
14
15 //the left and right parts of the slingshot
16 public Transform LeftSlingshotOrigin, RightSlingshotOrigin;
17
18 //two line renderers to simulate the "strings" of the slingshot
19 public LineRenderer SlingshotLineRenderer1;
20 public LineRenderer SlingshotLineRenderer2;
21
22 //this linerenderer will draw the projected trajectory of the thrown bird
23 public LineRenderer TrajectoryLineRenderer;
24
25 [HideInInspector]
26 //the bird to throw
27 public GameObject BirdToThrow;
28
29 //the position of the bird tied to the slingshot
30 public Transform BirdWaitPosition;
31
32 public float ThrowSpeed;
33
34 [HideInInspector]
35 public float TimeSinceThrown;
36
37 // Use this for initialization
38 void Start()
39 {
40 //set the sorting layer name for the line renderers
41 //for the slingshot renderers this did not work so I
42 //set the z on the background sprites to 10
43 //hope there's a better way around that!
44 SlingshotLineRenderer1.sortingLayerName = "Foreground";
45 SlingshotLineRenderer2.sortingLayerName = "Foreground";
46 TrajectoryLineRenderer.sortingLayerName = "Foreground";
47
48 slingshotState = SlingshotState.Idle;
49 SlingshotLineRenderer1.SetPosition(0, LeftSlingshotOrigin.position);
50 SlingshotLineRenderer2.SetPosition(0, RightSlingshotOrigin.position);
51
52 //pointing at the middle position of the two vectors
53 SlingshotMiddleVector = new Vector3((LeftSlingshotOrigin.position.x + RightSlingshotOrigin.position.x) / 2,
54 (LeftSlingshotOrigin.position.y + RightSlingshotOrigin.position.y) / 2, 0);
55 }
56
57 // Update is called once per frame
58 void Update()
59 {
60 switch (slingshotState)
61 {
62 case SlingshotState.Idle:
63 //fix bird's position
64 InitializeBird();
65 //display the slingshot "strings"
66 DisplaySlingshotLineRenderers();
67 if (Input.GetMouseButtonDown(0))
68 {
69 //get the point on screen user has tapped
70 Vector3 location = Camera.main.ScreenToWorldPoint(Input.mousePosition);
71 //if user has tapped onto the bird
72 if (BirdToThrow.GetComponent<CircleCollider2D>() == Physics2D.OverlapPoint(location))
73 {
74 slingshotState = SlingshotState.UserPulling;
75 }
76 }
77 break;
78 case SlingshotState.UserPulling:
79 DisplaySlingshotLineRenderers();
80
81 if (Input.GetMouseButton(0))
82 {
83 //get where user is tapping
84 Vector3 location = Camera.main.ScreenToWorldPoint(Input.mousePosition);
85 location.z = 0;
86 //we will let the user pull the bird up to a maximum distance
87 if (Vector3.Distance(location, SlingshotMiddleVector) > 1.5f)
88 {
89 //basic vector maths :)
90 var maxPosition = (location - SlingshotMiddleVector).normalized * 1.5f + SlingshotMiddleVector;
91 BirdToThrow.transform.position = maxPosition;
92 }
93 else
94 {
95 BirdToThrow.transform.position = location;
96 }
97 float distance = Vector3.Distance(SlingshotMiddleVector, BirdToThrow.transform.position);
98 //display projected trajectory based on the distance
99 DisplayTrajectoryLineRenderer2(distance);
100 }
101 else//user has removed the tap
102 {
103 SetTrajectoryLineRenderesActive(false);
104 //throw the bird!!!
105 TimeSinceThrown = Time.time;
106 float distance = Vector3.Distance(SlingshotMiddleVector, BirdToThrow.transform.position);
107 if (distance > 1)
108 {
109 SetSlingshotLineRenderersActive(false);
110 slingshotState = SlingshotState.BirdFlying;
111 ThrowBird(distance);
112 }
113 else//not pulled long enough, so reinitiate it
114 {
115 //distance/10 was found with trial and error :)
116 //animate the bird to the wait position
117 BirdToThrow.transform.positionTo(distance / 10, //duration
118 BirdWaitPosition.transform.position). //final position
119 setOnCompleteHandler((x) =>
120 {
121 x.complete();
122 x.destroy();
123 InitializeBird();
124 });
125
126 }
127 }
128 break;
129 case SlingshotState.BirdFlying:
130 break;
131 default:
132 break;
133 }
134
135 }
136
137 private void ThrowBird(float distance)
138 {
139 //get velocity
140 Vector3 velocity = SlingshotMiddleVector - BirdToThrow.transform.position;
141 BirdToThrow.GetComponent<Bird>().OnThrow(); //make the bird aware of it
142 //old and alternative way
143 //BirdToThrow.GetComponent<Rigidbody2D>().AddForce
144 // (new Vector2(v2.x, v2.y) * ThrowSpeed * distance * 300 * Time.deltaTime);
145 //set the velocity
146 BirdToThrow.GetComponent<Rigidbody2D>().velocity = new Vector2(velocity.x, velocity.y) * ThrowSpeed * distance;
147
148
149 //notify interested parties that the bird was thrown
150 if (BirdThrown != null)
151 BirdThrown(this, EventArgs.Empty);
152 }
153
154 public event EventHandler BirdThrown;
155
156 private void InitializeBird()
157 {
158 //initialization of the ready to be thrown bird
159 BirdToThrow.transform.position = BirdWaitPosition.position;
160 slingshotState = SlingshotState.Idle;
161 SetSlingshotLineRenderersActive(true);
162 }
163
164 void DisplaySlingshotLineRenderers()
165 {
166 SlingshotLineRenderer1.SetPosition(1, BirdToThrow.transform.position);
167 SlingshotLineRenderer2.SetPosition(1, BirdToThrow.transform.position);
168 }
169
170 void SetSlingshotLineRenderersActive(bool active)
171 {
172 SlingshotLineRenderer1.enabled = active;
173 SlingshotLineRenderer2.enabled = active;
174 }
175
176 void SetTrajectoryLineRenderesActive(bool active)
177 {
178 TrajectoryLineRenderer.enabled = active;
179 }
180
181
182 /// <summary>
183 /// Another solution (a great one) can be found here
184 /// http://wiki.unity3d.com/index.php?title=Trajectory_Simulation
185 /// </summary>
186 /// <param name="distance"></param>
187 void DisplayTrajectoryLineRenderer2(float distance)
188 {
189 SetTrajectoryLineRenderesActive(true);
190 Vector3 v2 = SlingshotMiddleVector - BirdToThrow.transform.position;
191 int segmentCount = 15;
192 float segmentScale = 2;
193 Vector2[] segments = new Vector2[segmentCount];
194
195 // The first line point is wherever the player's cannon, etc is
196 segments[0] = BirdToThrow.transform.position;
197
198 // The initial velocity
199 Vector2 segVelocity = new Vector2(v2.x, v2.y) * ThrowSpeed * distance;
200
201 float angle = Vector2.Angle(segVelocity, new Vector2(1, 0));
202 float time = segmentScale / segVelocity.magnitude;
203 for (int i = 1; i < segmentCount; i++)
204 {
205 //x axis: spaceX = initialSpaceX + velocityX * time
206 //y axis: spaceY = initialSpaceY + velocityY * time + 1/2 * accelerationY * time ^ 2
207 //both (vector) space = initialSpace + velocity * time + 1/2 * acceleration * time ^ 2
208 float time2 = i * Time.fixedDeltaTime * 5;
209 segments[i] = segments[0] + segVelocity * time2 + 0.5f * Physics2D.gravity * Mathf.Pow(time2, 2);
210 }
211
212 TrajectoryLineRenderer.SetVertexCount(segmentCount);
213 for (int i = 0; i < segmentCount; i++)
214 TrajectoryLineRenderer.SetPosition(i, segments[i]);
215 }
216
217
218
219 ///http://opengameart.org/content/forest-themed-sprites
220 ///forest sprites found on opengameart.com
221 ///© 2012-2013 Julien Jorge <julien.jorge@stuff-o-matic.com>
222
223 }
2 using System.Collections;
3 using Assets.Scripts;
4 using System;
5
6 public class SlingShot : MonoBehaviour
7 {
8
9 //a vector that points in the middle between left and right parts of the slingshot
10 private Vector3 SlingshotMiddleVector;
11
12 [HideInInspector]
13 public SlingshotState slingshotState;
14
15 //the left and right parts of the slingshot
16 public Transform LeftSlingshotOrigin, RightSlingshotOrigin;
17
18 //two line renderers to simulate the "strings" of the slingshot
19 public LineRenderer SlingshotLineRenderer1;
20 public LineRenderer SlingshotLineRenderer2;
21
22 //this linerenderer will draw the projected trajectory of the thrown bird
23 public LineRenderer TrajectoryLineRenderer;
24
25 [HideInInspector]
26 //the bird to throw
27 public GameObject BirdToThrow;
28
29 //the position of the bird tied to the slingshot
30 public Transform BirdWaitPosition;
31
32 public float ThrowSpeed;
33
34 [HideInInspector]
35 public float TimeSinceThrown;
36
37 // Use this for initialization
38 void Start()
39 {
40 //set the sorting layer name for the line renderers
41 //for the slingshot renderers this did not work so I
42 //set the z on the background sprites to 10
43 //hope there's a better way around that!
44 SlingshotLineRenderer1.sortingLayerName = "Foreground";
45 SlingshotLineRenderer2.sortingLayerName = "Foreground";
46 TrajectoryLineRenderer.sortingLayerName = "Foreground";
47
48 slingshotState = SlingshotState.Idle;
49 SlingshotLineRenderer1.SetPosition(0, LeftSlingshotOrigin.position);
50 SlingshotLineRenderer2.SetPosition(0, RightSlingshotOrigin.position);
51
52 //pointing at the middle position of the two vectors
53 SlingshotMiddleVector = new Vector3((LeftSlingshotOrigin.position.x + RightSlingshotOrigin.position.x) / 2,
54 (LeftSlingshotOrigin.position.y + RightSlingshotOrigin.position.y) / 2, 0);
55 }
56
57 // Update is called once per frame
58 void Update()
59 {
60 switch (slingshotState)
61 {
62 case SlingshotState.Idle:
63 //fix bird's position
64 InitializeBird();
65 //display the slingshot "strings"
66 DisplaySlingshotLineRenderers();
67 if (Input.GetMouseButtonDown(0))
68 {
69 //get the point on screen user has tapped
70 Vector3 location = Camera.main.ScreenToWorldPoint(Input.mousePosition);
71 //if user has tapped onto the bird
72 if (BirdToThrow.GetComponent<CircleCollider2D>() == Physics2D.OverlapPoint(location))
73 {
74 slingshotState = SlingshotState.UserPulling;
75 }
76 }
77 break;
78 case SlingshotState.UserPulling:
79 DisplaySlingshotLineRenderers();
80
81 if (Input.GetMouseButton(0))
82 {
83 //get where user is tapping
84 Vector3 location = Camera.main.ScreenToWorldPoint(Input.mousePosition);
85 location.z = 0;
86 //we will let the user pull the bird up to a maximum distance
87 if (Vector3.Distance(location, SlingshotMiddleVector) > 1.5f)
88 {
89 //basic vector maths :)
90 var maxPosition = (location - SlingshotMiddleVector).normalized * 1.5f + SlingshotMiddleVector;
91 BirdToThrow.transform.position = maxPosition;
92 }
93 else
94 {
95 BirdToThrow.transform.position = location;
96 }
97 float distance = Vector3.Distance(SlingshotMiddleVector, BirdToThrow.transform.position);
98 //display projected trajectory based on the distance
99 DisplayTrajectoryLineRenderer2(distance);
100 }
101 else//user has removed the tap
102 {
103 SetTrajectoryLineRenderesActive(false);
104 //throw the bird!!!
105 TimeSinceThrown = Time.time;
106 float distance = Vector3.Distance(SlingshotMiddleVector, BirdToThrow.transform.position);
107 if (distance > 1)
108 {
109 SetSlingshotLineRenderersActive(false);
110 slingshotState = SlingshotState.BirdFlying;
111 ThrowBird(distance);
112 }
113 else//not pulled long enough, so reinitiate it
114 {
115 //distance/10 was found with trial and error :)
116 //animate the bird to the wait position
117 BirdToThrow.transform.positionTo(distance / 10, //duration
118 BirdWaitPosition.transform.position). //final position
119 setOnCompleteHandler((x) =>
120 {
121 x.complete();
122 x.destroy();
123 InitializeBird();
124 });
125
126 }
127 }
128 break;
129 case SlingshotState.BirdFlying:
130 break;
131 default:
132 break;
133 }
134
135 }
136
137 private void ThrowBird(float distance)
138 {
139 //get velocity
140 Vector3 velocity = SlingshotMiddleVector - BirdToThrow.transform.position;
141 BirdToThrow.GetComponent<Bird>().OnThrow(); //make the bird aware of it
142 //old and alternative way
143 //BirdToThrow.GetComponent<Rigidbody2D>().AddForce
144 // (new Vector2(v2.x, v2.y) * ThrowSpeed * distance * 300 * Time.deltaTime);
145 //set the velocity
146 BirdToThrow.GetComponent<Rigidbody2D>().velocity = new Vector2(velocity.x, velocity.y) * ThrowSpeed * distance;
147
148
149 //notify interested parties that the bird was thrown
150 if (BirdThrown != null)
151 BirdThrown(this, EventArgs.Empty);
152 }
153
154 public event EventHandler BirdThrown;
155
156 private void InitializeBird()
157 {
158 //initialization of the ready to be thrown bird
159 BirdToThrow.transform.position = BirdWaitPosition.position;
160 slingshotState = SlingshotState.Idle;
161 SetSlingshotLineRenderersActive(true);
162 }
163
164 void DisplaySlingshotLineRenderers()
165 {
166 SlingshotLineRenderer1.SetPosition(1, BirdToThrow.transform.position);
167 SlingshotLineRenderer2.SetPosition(1, BirdToThrow.transform.position);
168 }
169
170 void SetSlingshotLineRenderersActive(bool active)
171 {
172 SlingshotLineRenderer1.enabled = active;
173 SlingshotLineRenderer2.enabled = active;
174 }
175
176 void SetTrajectoryLineRenderesActive(bool active)
177 {
178 TrajectoryLineRenderer.enabled = active;
179 }
180
181
182 /// <summary>
183 /// Another solution (a great one) can be found here
184 /// http://wiki.unity3d.com/index.php?title=Trajectory_Simulation
185 /// </summary>
186 /// <param name="distance"></param>
187 void DisplayTrajectoryLineRenderer2(float distance)
188 {
189 SetTrajectoryLineRenderesActive(true);
190 Vector3 v2 = SlingshotMiddleVector - BirdToThrow.transform.position;
191 int segmentCount = 15;
192 float segmentScale = 2;
193 Vector2[] segments = new Vector2[segmentCount];
194
195 // The first line point is wherever the player's cannon, etc is
196 segments[0] = BirdToThrow.transform.position;
197
198 // The initial velocity
199 Vector2 segVelocity = new Vector2(v2.x, v2.y) * ThrowSpeed * distance;
200
201 float angle = Vector2.Angle(segVelocity, new Vector2(1, 0));
202 float time = segmentScale / segVelocity.magnitude;
203 for (int i = 1; i < segmentCount; i++)
204 {
205 //x axis: spaceX = initialSpaceX + velocityX * time
206 //y axis: spaceY = initialSpaceY + velocityY * time + 1/2 * accelerationY * time ^ 2
207 //both (vector) space = initialSpace + velocity * time + 1/2 * acceleration * time ^ 2
208 float time2 = i * Time.fixedDeltaTime * 5;
209 segments[i] = segments[0] + segVelocity * time2 + 0.5f * Physics2D.gravity * Mathf.Pow(time2, 2);
210 }
211
212 TrajectoryLineRenderer.SetVertexCount(segmentCount);
213 for (int i = 0; i < segmentCount; i++)
214 TrajectoryLineRenderer.SetPosition(i, segments[i]);
215 }
216
217
218
219 ///http://opengameart.org/content/forest-themed-sprites
220 ///forest sprites found on opengameart.com
221 ///© 2012-2013 Julien Jorge <julien.jorge@stuff-o-matic.com>
222
223 }